
package com.ldzhao.blog.util;

import com.ldzhao.blog.exception.BlogFileException;
import com.ldzhao.blog.model.enums.QiniuUploadType;
import com.ldzhao.blog.service.SysAttachService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Arrays;
import java.util.UUID;

/**
 * 文件操作工具类
 */
@Slf4j
public class FileUtil {
    private static final String[] PICTURE_SUFFIXS = {".jpg", ".jpeg", ".png", ".gif", ".bmp"};
    public static final String CLASSPATH = BlogUtils.getUplodFilePath();

    /**
     * 删除目录，返回删除的文件数
     *
     * @param rootPath 待删除的目录
     * @param fileNum  已删除的文件个数
     * @return 已删除的文件个数
     */
    public static int deleteFiles(String rootPath, int fileNum) {
        File file = new File(rootPath);
        if (!file.exists()) {
            return -1;
        }
        if (file.isDirectory()) {
            File[] sonFiles = file.listFiles();
            if (sonFiles != null && sonFiles.length > 0) {
                for (File sonFile : sonFiles) {
                    if (sonFile.isDirectory()) {
                        fileNum = deleteFiles(sonFile.getAbsolutePath(), fileNum);
                    } else {
                        sonFile.delete();
                        fileNum++;
                    }
                }
            }
        } else {
            file.delete();
        }
        return fileNum;
    }


    public static String getPrefix(File file) {
        return getPrefix(file.getName());
    }

    public static String getPrefix(String fileName) {
        int idx = fileName.lastIndexOf(".");
        int xie = fileName.lastIndexOf("/");
        idx = idx == -1 ? fileName.length() : idx;
        xie = xie == -1 ? 0 : xie + 1;
        return fileName.substring(xie, idx);
    }

    public static String getSuffix(File file) {
        return getSuffix(file.getName());
    }

    public static String getSuffix(String fileName) {
        int idx = fileName.lastIndexOf(".");
        idx = idx == -1 ? fileName.length() : idx;
        return fileName.substring(idx);
    }

    public static boolean isPicture(String suffix) {
        return !StringUtils.isEmpty(suffix) && Arrays.asList(PICTURE_SUFFIXS).contains(suffix.toLowerCase());
    }

    public static void mkdirs(String filePath) {
        File file = new File(filePath);
        mkdirs(file);
    }

    public static void mkdirs(File file) {
        if (!file.exists()) {
            if (file.isDirectory()) {
                file.mkdirs();
            } else {
                file.getParentFile().mkdirs();
            }
        }
    }

    public static String uploadToQiniu(MultipartFile multipartFile, QiniuUploadType uploadType, boolean canBeNull) {
        // 不可为空并且file为空，抛出异常
        if (!canBeNull && null == multipartFile) {
            throw new BlogFileException("请选择图片");
        }
        // 可为空并且file为空，忽略后边的代码，返回null
        if (canBeNull && null == multipartFile) {
            return null;
        }
        try {
            boolean isPicture = FileUtil.isPicture(FileUtil.getSuffix(multipartFile.getOriginalFilename()));
            if (isPicture) {
                String filename = multipartFile.getOriginalFilename();
                String fkey = BlogUtils.getFileKey(filename);
                File file = new File(CLASSPATH + fkey);
                try {
                    FileCopyUtils.copy(multipartFile.getInputStream(), new FileOutputStream(file));
                } catch (IOException e) {
                    throw new BlogFileException("上传图片到七牛云发生异常，请检查七牛配置是否正常", e);
                }
                AliyunOSSUtil.upload("zblog"+fkey,file);
                SysAttachService sysAttachService = SpringBeanFactory.getBean(SysAttachService.class);
                sysAttachService.save(filename, fkey, "image", 1);
                return fkey;
            } else {
                throw new BlogFileException("只支持图片");
            }
        } catch (Exception e) {
            throw new BlogFileException("上传图片到七牛云发生异常，请检查七牛配置是否正常", e);
        }
    }

    private static String getSuffixByUrl(String imgUrl) {
        String defaultSuffix = "png";
        if (org.apache.commons.lang3.StringUtils.isEmpty(imgUrl)) {
            return defaultSuffix;
        }
        String temStr = imgUrl.substring(imgUrl.lastIndexOf("/"));
        int index = temStr.lastIndexOf(".");
        return -1 == index ? defaultSuffix : temStr.substring(index + 1);
    }

    /**
     * @param imgUrl    网络图片地址
     * @param localPath 待保存的本地地址
     */
    public static String download(String imgUrl, String localPath) {
        log.debug("download img >> %s", imgUrl);

        String fileName = localPath + File.separator + UUID.randomUUID().toString() + "." + getSuffixByUrl(imgUrl);
        try (InputStream is = getInputStreamByUrl(checkUrl(imgUrl));
             FileOutputStream fos = new FileOutputStream(fileName)) {
            if (null == is) {
                return null;
            }
            File file = new File(localPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            int bytesWritten = 0, byteCount = 0;
            byte[] b = new byte[1024];
            while ((byteCount = is.read(b)) != -1) {
                fos.write(b, bytesWritten, byteCount);
            }
        } catch (IOException e) {
            log.error("Error.", e);
            return null;
        }
        return fileName;
    }

    private static InputStream getInputStreamByUrl(String url) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36");
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        InputStream in = null;
        try {
            response = httpclient.execute(httpGet);
            in = response.getEntity().getContent();
            if (response.getStatusLine().getStatusCode() == 200) {
                return in;
            } else {
                log.error("Error. %s", parseInputStream(in));
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("Error.", e);
        }
        return in;
    }

    private static String parseInputStream(InputStream in) throws IOException {
        String result = "";
        StringBuffer content = null;
        if (null != in) {
            BufferedReader r = new BufferedReader(new InputStreamReader(in));
            content = new StringBuffer();
            String line = "";
            while ((line = r.readLine()) != null) {
                content.append(line);
            }
            result = content.toString();
        }
        return result;
    }

    /**
     * 校验Url，并返回完整的url
     *
     * @param url 待校验的url
     */
    private static String checkUrl(String url) {
        if (!org.apache.commons.lang3.StringUtils.isEmpty(url)) {
            if (url.startsWith("http://") || url.startsWith("https://")) {
                return url;
            }
            return url.startsWith("//") ? "https:" + url : "http://" + url;
        }
        return null;
    }

    /**
     * 将网络图片转存到七牛云
     *
     * @param imgUrl 网络图片地址
     */
    public static String convertToQiniu(String imgUrl) {
        log.debug("download img >> %s", imgUrl);
        String qiniuImgPath = null;
        try (InputStream is = getInputStreamByUrl(checkUrl(imgUrl));) {
            String filename = imgUrl;
            String fkey = BlogUtils.getFileKey(filename);
            File file = new File(CLASSPATH + fkey);
            try {
                FileCopyUtils.copy(is, new FileOutputStream(file));
            } catch (IOException e) {
                throw new BlogFileException("上传图片到七牛云发生异常，请检查七牛配置是否正常", e);
            }
            AliyunOSSUtil.upload("zblog"+fkey,file);
            SysAttachService sysAttachService = SpringBeanFactory.getBean(SysAttachService.class);
            sysAttachService.save(filename, fkey, "image", 1);
            return fkey;
        } catch (Exception e) {
            throw new BlogFileException("上传图片到七牛云发生异常，请检查七牛配置是否正常", e);
        }
    }
}
